package structx

type CacheChain[R any, T any] interface {
	Execute(rec *SearchRequest[R, T]) error
}

type CacheChainItem[R any, T any] struct {
	Handle  func(*SearchRequest[R, T]) error
	Success func(data T) error
}

func (r *CacheChainItem[R, T]) Execute(rec *SearchRequest[R, T]) error {
	if r.Handle != nil {
		err := r.Handle(rec)
		if err != nil {
			return err
		} else {
			if r.Success != nil {
				err = r.Success(rec.Resp)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}

type SearchRequest[R any, T any] struct {
	Req  R
	Resp T
}

func (r *SearchRequest[R, T]) Run(chains ...CacheChain[R, T]) error {
	var err error
	for _, chain := range chains {
		if err = chain.Execute(r); err == nil {
			break
		}
	}
	return err
}
